#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
配置数据类
Configuration Data Classes

定义系统配置的数据结构
"""

from dataclasses import dataclass, field
from typing import Dict, List, Optional


@dataclass
class LoggingConfig:
    """日志配置"""
    file_level: str = "DEBUG"
    console_level: str = "INFO"
    format: str = "[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s"
    datefmt: str = "%H:%M:%S"
    file_path: str = "logs/app.log"
    max_file_size: int = 10485760  # 10MB
    backup_count: int = 5


@dataclass
class ModelConfig:
    """模型配置"""
    path: str = "model/yolo11n_face_detect_bayese_320x320_nv12.bin"
    confidence_threshold: float = 0.6
    iou_threshold: float = 0.45
    input_image_size: int = 320
    dfl_bins: int = 16
    anchor_shapes: List[Dict[str, int]] = field(default_factory=lambda: [
        {"size": 40, "stride": 8},
        {"size": 20, "stride": 16},
        {"size": 10, "stride": 32},
    ])


@dataclass
class CameraConfig:
    """摄像头配置"""
    device_path: str = "/dev/video0"
    width: int = 640
    height: int = 480
    fps: int = 30


@dataclass
class WebConfig:
    """Web服务配置"""
    host: str = "0.0.0.0"
    port: int = 5000
    debug: bool = False
    threaded: bool = True


@dataclass
class MCPConfig:
    """MCP服务配置"""
    host: str = "0.0.0.0"
    port: int = 8000
    name: str = "FaceTrackerServer"
    description: str = "智能人脸追踪系统MCP服务器"


@dataclass
class GimbalConfig:
    """云台配置"""
    serial_port: str = "/dev/ttyS1"
    baudrate: int = 115200
    pan_pin: int = 3
    tilt_pin: int = 4
    init_pan_angle: float = 135.0
    init_tilt_angle: float = 135.0
    angle_range: List[int] = field(default_factory=lambda: [0, 270])
    supported_pins: List[int] = field(default_factory=lambda: [2, 3, 4, 6, 44, 45, 46, 7, 10])
    min_pan: float = 0.0
    max_pan: float = 270.0
    min_tilt: float = 0.0
    max_tilt: float = 270.0


@dataclass
class PidAxisConfig:
    """单轴PID参数"""
    kp: float = 0.6
    ki: float = 0.0
    kd: float = 0.0
    smoothing_factor: float = 0.9
    max_integral: float = 20.0
    first_update_factor: float = 0.3
    output_limit: float = 100.0
    integral_error_threshold: float = 10.0


@dataclass
class PidConfig:
    """PID 控制配置"""
    pan: PidAxisConfig = field(default_factory=PidAxisConfig)
    tilt: PidAxisConfig = field(default_factory=PidAxisConfig)


@dataclass
class KalmanFilterConfig:
    """卡尔曼滤波配置"""
    dt: float = 0.1
    process_noise_scale: float = 0.01
    measurement_noise_scale: float = 0.1
    prediction_time_factor: float = 1.5
    velocity_threshold: float = 50.0
    acceleration_enabled: bool = True
    adaptive_noise: bool = True


@dataclass
class ServoTrackingConfig:
    """舵机自动追踪配置"""
    face_timeout: float = 0.8
    movement_threshold: float = 3.0
    angle_adjust_factor: float = 0.05
    min_servo_interval: float = 0.01
    distance_threshold: float = 80.0
    sleep_interval: float = 0.03
    first_detection_factor: float = 0.25
    max_angle_change: float = 8.0
    center_deadzone: float = 60.0
    prediction_enabled: bool = True
    prediction_time: float = 0.2
    prediction_weight: float = 0.7
    max_prediction_distance: float = 200.0
    angle_smoothing_factor: float = 0.5


@dataclass
class TargetTrackingConfig:
    """目标评分与状态配置"""
    confidence_weight: float = 0.25
    size_weight: float = 0.75
    persistence_weight: float = 0.2
    position_weight: float = 0.3
    target_switch_threshold: float = 0.2
    target_timeout: float = 1.0
    max_history_count: int = 10
    max_position_distance: float = 100.0
    direction_threshold: float = 10.0


@dataclass
class SerialConfig:
    """串口配置"""
    port: str = "/dev/ttyS1"
    baudrate: int = 115200


@dataclass
class TrackingConfig:
    """追踪配置"""
    auto_enabled: bool = False
    kalman_enabled: bool = True
    prediction_enabled: bool = True
    target_center_threshold: int = 50  # 像素
    pid: PidConfig = field(default_factory=PidConfig)
    kalman: KalmanFilterConfig = field(default_factory=KalmanFilterConfig)
    servo_tracking: ServoTrackingConfig = field(default_factory=ServoTrackingConfig)
    target_tracking: TargetTrackingConfig = field(default_factory=TargetTrackingConfig)


@dataclass
class DetectionConfig:
    """检测配置"""
    class_names: List[str] = None
    colors: List[List[int]] = None
    font_scale: float = 1.0
    line_thickness: int = 2
    
    def __post_init__(self):
        if self.class_names is None:
            self.class_names = ["face"]
        if self.colors is None:
            self.colors = [[0, 255, 0]]  # 绿色人脸框


@dataclass
class Settings:
    """主配置类"""
    app_name: str = "智能人脸追踪系统"
    version: str = "2.0.0"
    environment: str = "development"
    
    logging: LoggingConfig = None
    model: ModelConfig = None
    camera: CameraConfig = None
    web: WebConfig = None
    mcp: MCPConfig = None
    gimbal: GimbalConfig = None
    tracking: TrackingConfig = None
    detection: DetectionConfig = None
    serial: SerialConfig = None
    
    def __post_init__(self):
        # 初始化子配置对象
        if self.logging is None:
            self.logging = LoggingConfig()
        if self.model is None:
            self.model = ModelConfig()
        if self.camera is None:
            self.camera = CameraConfig()
        if self.web is None:
            self.web = WebConfig()
        if self.mcp is None:
            self.mcp = MCPConfig()
        if self.gimbal is None:
            self.gimbal = GimbalConfig()
        if self.tracking is None:
            self.tracking = TrackingConfig()
        if self.detection is None:
            self.detection = DetectionConfig()
        if self.serial is None:
            self.serial = SerialConfig()
